﻿using System;
using System.Runtime.InteropServices;

namespace simu_582.Data
{
    public class KgAccurateTimer
    {
        private delegate void TimeProc(int id, int msg, IntPtr user, int param1, int param2); 
        private uint mTimerId;
        Action mAction;
        private TimeProc mHandler;  // NOTE: declare at class scope so garbage collector doesn't release it!!!

        [DllImport("winmm.dll")]
        private static extern int timeBeginPeriod(int msec);
        [DllImport("winmm.dll")]
        private static extern int timeEndPeriod(int msec);
        [DllImport("winmm.dll")]
        private static extern uint timeSetEvent(int delay, int resolution, TimeProc handler, IntPtr user, int eventType);
        [DllImport("winmm.dll")]
        private static extern int timeKillEvent(uint id);
        
        

        private const int TIME_PERIODIC = 1;
        public KgAccurateTimer(int delay, Action action)
        {
            mAction = action;
            timeBeginPeriod(1);
            mHandler = new TimeProc(TimerCallback);
            mTimerId = timeSetEvent(delay, 0, mHandler, IntPtr.Zero, TIME_PERIODIC);
        }

        public void Stop()
        {
            int err = timeKillEvent(mTimerId);
            timeEndPeriod(1);
            System.Threading.Thread.Sleep(100);// Ensure callbacks are drained
        }

        private void TimerCallback(int id, int msg, IntPtr user, int dw1, int dw2)
        {
            if (mTimerId != 0)
                mAction();
        }
    }
}
